<?php
namespace Plu\Library\Services\Tga\Messageboard;

use Plu\Library\Services\ServiceBase,
    Plu\Library\Services\Redis\Room\RoomRedis,
    Plu\Library\Services\Redis\Blacklist\BlacklistRedis,
    Plu\Library\Models\Tga\Messageboard\Applicants as ApplicantsModel,
    Plu\Library\Models\Tga\Messageboard\Admire as AdmireModel,
    Httpful\Request as Request;

/**
 * @usage 
 * $service = new MessageboardService($appkey, $uid)
 * $service->validate()
 * $service->send()
 *
 */
class MessageboardService extends ServiceBase {
    //错误代码
    const SUCCESS            = 0;//成功 标识符0
    const ERROR_MESSAGE      = -2;//没有发言机会
    const ERROR_APPKEY       = -3;//appkey错误
    const ERROR_DATA_START   = -4;//比赛未开始
    const ERROR_DATA_END     = -5;//比赛已结束
    const ERROR_APP_UNABLE   = -6;//活动未启用
    const ERROR_VALIDATION   = -7;//校验失败
    const ERROR_ADMIRE      = -8;//已经点过赞了
    const ERROR_BlOCK      = -9;//被禁言

    protected $_uid;

    protected $_appkey    = null;

    protected $_verified  = false;//验证通过

    protected $_errorInfo = [];

    protected $_passInfo  = '';//验证的通过后的数据

    protected $_appInfo   = null;

    protected $deleteflag = 0;

    protected $image  = '';


    public function __construct($appkey, $uid=0) {
        $this->_appkey = $appkey;
        $this->_uid    = $uid;

        $this->_redis = new RedisService();

        $this->_appInfo = $this->_redis->getAppInfo($appkey);

        $this->now = time();
    }

    //获取活动信息
    public function getAppInfo() {
        return $this->_appInfo;
    }

    /**
     *  增加发言
     *
     *  1. check
     *  2. insert
     */
    public function send(){
        if (!$this->_verified) {
            $this->setErrorMessage(self::ERROR_VALIDATION, 'validation', "校验数据不成功");
            return false;
        }

        $isSuccess = ApplicantsModel::addItem($this->_appkey, $this->_uid, $this->_passInfo, $this->image);

        //存入信息到redis中
        if ($isSuccess) {
            $date = date('Ymd');
            $this->_redis->incrMessage($this->_appkey, $date, $this->_uid);
            $this->_redis->setnodate($this->_appkey, $this->_uid, $this->now);
            return true;
        }
        //祝福次数+1
        return false;
    }

    /**
     * 按点赞数获取发言
     */
    public function getList($limit){
        $result = ApplicantsModel::getList($this->_appkey, $this->deleteflag, $limit);
        return $result;
    }
    

    /**
     * 根据id获取发言
     */
    public function getListByIds($start, $limit){
        $result = ApplicantsModel::getListById($this->_appkey, $start, $limit, $this->deleteflag);
        return $result;
    }

    /**
     * 获取所有id
     */
    public function getIds(){
        $result = ApplicantsModel::getIds($this->_appkey, $this->deleteflag);
        return $result;
    }

    /**
     * 获取发言总条数
     */
    public function num(){
        $result = ApplicantsModel::num($this->_appkey, $this->deleteflag);
        return $result;
    }


    /**
    *点赞
    */
    public function addAdmire($messageid){
        if (!$this->_verified) {
            $this->setErrorMessage(self::ERROR_VALIDATION, 'validation', "校验数据不成功");
            return false;
        }

        $isSuccess = ApplicantsModel::updateMesById($messageid);

        //存入信息到redis中
        if ($isSuccess) {
            $date = date('Ymd');
            $field = $this->_uid.'_'.$messageid;
            AdmireModel::addItem($this->_appkey, $this->_uid, $messageid);
            $this->_redis->incrAdmire($this->_appkey, $date, $field);
            return true;
        }

        return false;
    }

    /**
     * 通过屏蔽接口判断发言是否包含敏感字符
     */
    public  function sensitive($str) {
        $apiUrl = "http://mbgo.plu.cn/valid_msg?msg=".urlencode($str);
        $result = Request::get($apiUrl)->timeout(10)->expectsJson()->send();
        if ($result->hasBody()) {
            $body = $result->body;
            return !$body->isBlock;
        } else {
            return false;
        }
    }


    /**
     * 校验数据是否合法
     */
    public function validate($postData, $messageid = 0, $admire = false) {
        $app = $this->getAppInfo();

        //活动未启用
        if ( $app['enable'] != 1 || empty($app) ) {
            $this->setErrorMessage(self::ERROR_APP_UNABLE, 'unable', "不存在该报名活动");
            return false;
        }
        //活动未开始
        if ( $this->now < $app['starttime']){
            $this->setErrorMessage(self::ERROR_DATA_START, 'starttime', "活动未开始！");
            return false;
        }

        //活动已经结束
        if( $this->now > $app['endtime']) {
            $this->setErrorMessage(self::ERROR_DATA_END, 'endtime', "活动已结束！");
            return false;
        }


        //判断此用户是否可以点赞该条发言
        $validationService = new ValidationService($this->_appkey);

        if($admire) {
            $field = $this->_uid."_".$messageid;
            $lastupdate = $this->_redis->getAdmire($this->_appkey, date('Ymd'), $field);
            $message = $validationService->admireCheck($field);
            if(!$message){
                $this->setErrorMessage(self::ERROR_ADMIRE, 'noadmire', "您已经点过赞了！");
                return false; 
            }
        } else {
            $message = $validationService->messageCheck($this->_uid);
            if(!$message){
                $this->setErrorMessage(self::ERROR_MESSAGE, 'nomessage', "您目前没有发言机会！");
                return false; 
            }

            //禁言用户
            $BlacklistRedis = new BlacklistRedis();
            $blocktime = $BlacklistRedis->hasBlocked(0, $this->_uid);
            if($blocktime >= $this->now){
                $this->setErrorMessage(self::ERROR_BlOCK, 'block', "您目前被禁言了！");
                return false; 
            }

            //字符数限制

            //数据敏感词过滤
            $sensitive = $this->sensitive($postData);
            if(!$sensitive){
                $this->setErrorMessage(self::ERROR_VALIDATION, 'sensitive', "抱歉，您的祝福未通过审核，重新发一个吧！");
                return false;
            }
            //html过滤
            $data = '';
            $data = htmlspecialchars($postData);

            //数据通过
            $this->_passInfo = $data;

        }
        $this->_verified = true;
        return true;
    }

    public function getErrorMessages(){
        return $this->_errorInfo;
    }

    /**
     *  错误设置与获取
     */
    protected function setErrorMessage($errorCode, $field, $errorInfo){
        $this->_errorInfo[] = array(
            'code'      => $errorCode,
            'field'     => $field,
            'errorInfo' => $errorInfo
        );
    }
}
?>
